package main;

import com.github.crab2died.ExcelUtils;
import com.github.crab2died.sheet.wrapper.NoTemplateSheetWrapper;
import model.statical.Model;
import model.simulation.OutPutData;
import model.simulation.RankLayer;
import model.simulation.SiADepartment;
import model.simulation.SiBDepartment;
import model.simulation.SiCDepartment;
import model.simulation.SiDDepartment;
import model.simulation.SiDepartment;
import model.simulation.SiModel;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class SimulationMain
{

	public static void main(String[] args)
	{
		List<SiModel> actualList, authorizedList = new ArrayList<>();
		try
		{
			actualList = ExcelUtils.getInstance()
					.readExcel2Objects("数据模板/仿真初始数据.xlsx", SiModel.class, 1);
			List<Model> models = ExcelUtils.getInstance()
					.readExcel2Objects("数据模板/仿真初始数据.xlsx", Model.class, 0);
			for (Model model : models)
				authorizedList.add(new SiModel(model));
		} catch (Exception e)
		{
			e.printStackTrace();
			return;
		}

		calculate(actualList, authorizedList);
	}

	public static void calculate(File file)
	{
		List<SiModel> actualList, authorizedList = new ArrayList<>();
		try(InputStream inputStream = new FileInputStream(file))
		{
			actualList = ExcelUtils.getInstance().readExcel2Objects(inputStream,
					SiModel.class, 1);
		} catch (Exception e)
		{
			e.printStackTrace();
			return;
		}
		
		try(InputStream inputStream = new FileInputStream(file))
		{
			List<Model> models = ExcelUtils.getInstance()
					.readExcel2Objects(inputStream, Model.class, 0);
			for (Model model : models)
				authorizedList.add(new SiModel(model));
		} catch (Exception e)
		{
			e.printStackTrace();
			return;
		}

		calculate(actualList, authorizedList);
	}

	public static List<OutPutData> getOutPutDatas(List<SiDDepartment> allDDepartments)
	{
		ArrayList<OutPutData> outPutData = new ArrayList<>();
		for (SiDepartment dDepartment : allDDepartments)
			outPutData.add(new OutPutData(dDepartment));
		return outPutData;
	}

	public static List<OutPutData> getAOutPutDatas(
			List<SiADepartment> allADepartments)
	{
		ArrayList<OutPutData> outPutData = new ArrayList<>();
		for (SiADepartment dDepartment : allADepartments)
			outPutData.add(new OutPutData(dDepartment));
		return outPutData;
	}

	public static void calculate(List<SiModel> actualList,
			List<SiModel> authorizedList)
	{
		ArrayList<SiDDepartment> allDDepartments = new ArrayList<>();
		SiDDepartment tempDDepartment = null;
		for (SiModel model : authorizedList)
		{
			if (tempDDepartment == null
					|| !tempDDepartment.isModelInThisDDepartment(model))
			{
				tempDDepartment = new SiDDepartment(model);
				allDDepartments.add(tempDDepartment);
			}
			tempDDepartment.notMatchAuthorizedModels.add(model);
			model.setDepartment(tempDDepartment);
		}

		for (SiModel model : actualList)
		{
			for (SiDDepartment dDepartment : allDDepartments)
			{
				if (dDepartment.isModelInThisDDepartment(model))
				{
					dDepartment.notMatchActualModels.add(model);
					model.setDepartment(dDepartment);
					break;
				}
			}
		}

		List<SiCDepartment> allCDepartments = new ArrayList<>();
		SiCDepartment tempCDepartment = null;
		for (SiDDepartment dDepartment : allDDepartments)
		{
			if (tempCDepartment == null
					|| !tempCDepartment.isSubDepartmentInThis(dDepartment))
			{
				tempCDepartment = new SiCDepartment(dDepartment);
				allCDepartments.add(tempCDepartment);
			}
			tempCDepartment.addSubDepartment(dDepartment);
		}


		List<SiBDepartment> allBDepartments = new ArrayList<>();
		SiBDepartment tempBDepartment = null;
		for (SiCDepartment cDepartment : allCDepartments)
		{
			if (tempBDepartment == null
					|| !tempBDepartment.isSubDepartmentInThis(cDepartment))
			{
				tempBDepartment = new SiBDepartment(cDepartment);
				allBDepartments.add(tempBDepartment);
			}
			tempBDepartment.addSubDepartment(cDepartment);
		}

		List<SiADepartment> allADepartments = new ArrayList<>();
		SiADepartment tempADepartment = null;
		for (SiBDepartment bDepartment : allBDepartments)
		{
			if (tempADepartment == null
					|| !tempADepartment.isSubDepartmentInThis(bDepartment))
			{
				tempADepartment = new SiADepartment(bDepartment);
				allADepartments.add(tempADepartment);
			}
			tempADepartment.addSubDepartment(bDepartment);
		}

		RankLayer.initDatas(allDDepartments);

		List<NoTemplateSheetWrapper> sheets = new ArrayList<>();
		
		for (SiDDepartment dDepartment : allDDepartments)
			dDepartment.calculateStatisticData();
		sheets.add(new NoTemplateSheetWrapper(getOutPutDatas(allDDepartments),
				OutPutData.class, true, "第0年数据"));

		for (int i = 1; i <= 20; i++)
		{
			RankLayer.calculateNextYearDatas();
			sheets.add(new NoTemplateSheetWrapper(getOutPutDatas(allDDepartments),
					OutPutData.class, true, "第" + i + "年数据"));
		}

//		for (SiADepartment aDepartment : allADepartments)
//			aDepartment.calculateStatisticData();
//		sheets.add(new NoTemplateSheetWrapper(getAOutDatas(allADepartments),
//		OutData.class, true, "第0年数据"));
//		for (int i = 1; i <= 20; i++)
//		{
//			RankLayer.nextYear();
//			for (SiADepartment aDepartment : allADepartments)
//				aDepartment.calculateStatisticData();
//			sheets.add(new NoTemplateSheetWrapper(getAOutDatas(allADepartments),
//					OutData.class, true, "第" + i + "年数据"));
//		}

		try
		{
			ExcelUtils.getInstance().noTemplateSheet2Excel(sheets,
					"模拟仿真统计数据.xlsx");
			MainFrame.openFile(new File("模拟仿真统计数据.xlsx"));
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
